package com.hdl.school.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.eclipsesource.v8.V8;
import com.eclipsesource.v8.V8Array;
import com.eclipsesource.v8.V8Object;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StatusParser {
    private static StatusParser statusParser;
    private List<JSONObject> statusParserScripts;
    private Map<String, JSONObject> statusMap=new HashMap<String, JSONObject>();


    public static StatusParser getInstance(){
        if(statusParser==null){
            statusParser=new StatusParser();
        }
        return statusParser;
    }


    public List getStatusParserScripts() {
        return statusParserScripts;
    }

    public void setStatusParserScripts(List statusParserScripts) {
        this.statusParserScripts = statusParserScripts;
    }

    public JSONObject parseStatus(String portType, String code,String serialKey){
        String key=portType+"_"+code;
        if(serialKey!=null){
            key=portType+"_"+serialKey+"_"+code;
        }
        if(statusMap.containsKey(key)){
            return statusMap.get(key);
        }else{
            if (statusParserScripts != null && statusParserScripts.size() > 0) {
                for (int i = 0; i < statusParserScripts.size(); i++) {
                    JSONObject parser = statusParserScripts.get(i);
                    if (!parser.containsKey("matchRegex")) {
                        continue;
                    }
                    if ((!parser.containsKey("target")) || portType.equals(parser.getString("target"))) {
                        Pattern pattern = Pattern.compile(parser.getString("matchRegex"));
                        Matcher matcher = pattern.matcher(code);
                        if (matcher.find()) {
                            String parseCode = parser.getString("parseCode");
                            if (parseCode == null) {
                                continue;
                            }
                            parseCode = parseCode.replace("{$revCode}", code.substring(matcher.start()));
                            if(serialKey!=null){
                                parseCode = parseCode.replace("{$currentKey}", serialKey);
                            }

                            try {
                                V8 runtime = V8.createV8Runtime();
                                V8Object parsedObj = runtime.executeObjectScript(parseCode);
                                V8Object json = runtime.getObject("JSON");
                                V8Array args = new V8Array(runtime).push(parsedObj);
                                String result = (String) json.executeFunction("stringify", args);
                                args.release();
                                json.release();
                                parsedObj.release();
                                runtime.release();
                                JSONObject outputObj = JSON.parseObject(result);
                                statusMap.put(key,outputObj);
                                return outputObj;
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            break;
                        }
                    }
                }
            }
            return null;
        }
    }
}
